package baiqitun.netfiles.service.impl;

import baiqitun.akutils.PathUtil;
import baiqitun.netfiles.config.properties.NetFilesProperties;
import baiqitun.netfiles.exception.NetFilesException;
import baiqitun.netfiles.entity.SysDirectory;
import baiqitun.netfiles.entity.SysFile;
import baiqitun.netfiles.service.SysDirectoryService;
import baiqitun.netfiles.service.SysFileService;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;

/**
 * @author kedaji
 */
@Service
public class SysDirectoryServiceImpl extends MappingServiceImpl<SysDirectory> implements SysDirectoryService {
    @Autowired
    private NetFilesProperties netFilesProperties;
    @Autowired
    private SysFileService sysFileService;

    @Override
    public SysDirectory dir(String id) {
        // 先去数据库查此目录
        SysDirectory result = getByPath(id);
        if (result == null){
            throw new NetFilesException("文件或目录不存在!");
        }
        // 然后根据id对应的路径获取此目录的子文件列表
        List<SysDirectory> directories = new LinkedList<>();
        List<SysFile> files = new LinkedList<>();

        try {
            String mappingPath = getMappingPath(id);
            if (result.getParentId() != null && !result.getParentId().isEmpty()){
                byte[] serialized = ObjectUtil.serialize(get(result.getParentId()));
                SysDirectory copyObject = ObjectUtil.deserialize(serialized);
                copyObject.setName("..");
                directories.add(copyObject);
            }

            Files.list(Paths.get(mappingPath)).forEach(childPath->{
                if (Files.isDirectory(childPath)){
                    SysDirectory childDirectory = getByPath(childPath.toString());
                    if (childDirectory == null){
                        childDirectory = new SysDirectory();
                        childDirectory.setParentId(result.getId());
                        childDirectory.setRootId(result.getRootId());
                        childDirectory.setName(PathUtil.getName(childPath));
                        // 建立映射关系
                        save(childPath.toString(), childDirectory);
                    }
                    directories.add(childDirectory);
                } else {
                    SysFile file = sysFileService.getByPath(childPath.toString());
                    if (file == null){
                        file = new SysFile();
                        file.setName(PathUtil.getName(childPath));
                        file.setParentId(result.getId());
                        file.setRootId(result.getRootId());

                        List<String> images = netFilesProperties.getSupportSuffix().getImages();
                        List<String> videos = netFilesProperties.getSupportSuffix().getVideos();
                        List<String> texts = netFilesProperties.getSupportSuffix().getTexts();

                        String extName = FileUtil.extName(childPath.toString());

                        if (images.contains(extName)){
                            file.setFileType("image");
                        } else if (videos.contains(extName)){
                            file.setFileType("video");
                        } else if (texts.contains(extName)){
                            file.setFileType("text");
                        } else {
                            file.setFileType("unknown");
                        }

                        // 建立映射关系
                        sysFileService.save(childPath.toString(), file);
                    }
                    files.add(file);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        result.setDirectories(directories);
        result.setFiles(files);
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<SysDirectory> listRoot() {
        return (List<SysDirectory>) getObject(formatKey("roots"));
    }
}
